import {mapConfig} from './mapConfig.js';
import {layerConfig} from './layerConfig.js';
import {hnJson} from '../libs/hn.js';

class GisApi {
  constructor() {
    this._map = null; // 地图对象
    this._vectorLayers = null; // 矢量图层对象
    this._uiMarkers = []; // UI标记数组
    this._worker = new Worker('./js/api/worker.js');
    this._worker.onmessage = this._handleWorkerMessage.bind(this);
    this._worker.onerror = (error) => console.error('Worker error:', error);
  }

  initMap() {
    this._initializeMap(); // 初始化地图
    this._initHnBoundary()
    this._initializeBaseLayers(); // 初始化基础图层
    this._initializeVectorLayers(); // 初始化矢量图层
  }

  // 初始化地图
  _initializeMap() {
    // eslint-disable-next-line no-undef
    this._map = new kcgis.Map('map', {...mapConfig});
  }

  _handleWorkerMessage(e) {
    const {taskType, result} = e.data;
    switch (taskType) {
      case 'kriging':
        this._addKrigingContoursToMap(result.k, result.l);
        break;
      // 可以添加更多的任务处理逻辑
      default:
        console.error('Unknown task type:', taskType);
    }
  }

  _initHnBoundary() {
    const boundaryVectorLayers = this._createBoundaryVectorLayer();
    fetch('./data/hn.json')
      .then(res => res.json())
      .then(json => {
        this._addBoundaryLines(json, boundaryVectorLayers);
        this._addBoundaryLabels(json, boundaryVectorLayers);
      });
  }

  _createBoundaryVectorLayer() {
    const boundaryVectorLayers = new kcgis.VectorLayer('boundary-vector-layers', {}).addTo(this._map);
    boundaryVectorLayers.setZIndex(2);
    return boundaryVectorLayers;
  }

  _addBoundaryLines(json, boundaryVectorLayers) {
    json.features.forEach(d => {
      if (d.properties.id === 0) {
        this._createOutlineLines(d.geometry.coordinates, boundaryVectorLayers);
      } else {
        this._createLine(d.geometry.coordinates, boundaryVectorLayers, 'rgba(244,255,49,1)', 1);
      }
    });
  }

  _createOutlineLines(coordinates, boundaryVectorLayers) {
    const outlines = [{color: 'rgba(74,152,114,0.32)', width: 6, dasharray: [2, 2, 2]}, {
      color: 'rgba(69,175,179,0.27)', width: 4, dasharray: [5, 5, 5]
    }, {color: 'rgba(0,0,0,1)', width: 2, dasharray: [8, 8, 8]},];

    outlines.forEach(outline => {
      const line = this._createLine(coordinates, boundaryVectorLayers, outline.color, outline.width, outline.dasharray);
      line.addTo(boundaryVectorLayers);
    });
  }

  _createLine(coordinates, boundaryVectorLayers, color, width, dasharray = [5, 5, 5]) {
    return new kcgis.LineString(coordinates, {
      symbol: {
        'smoothness': 1,
        'lineColor': color,
        'lineWidth': width,
        'lineDasharray': dasharray,
        'enableSimplify': true,
        'simplifyTolerance': 10
      }
    }).addTo(boundaryVectorLayers);
  }

  _addBoundaryLabels(json, boundaryVectorLayers) {
    json.properties.children.forEach(d => {
      this._createLabel(d, boundaryVectorLayers);
    });
  }

  _createLabel(t, boundaryVectorLayers) {
    // eslint-disable-next-line no-undef
    const text = new kcgis.Marker(t.centroid, {
      'properties': {
        'adcode': t.adcode, 'name': t.name,
      }, 'symbol': {
        'textFaceName': 'YouSheBiaoTiHei',
        'textName': '{name}',
        'textWeight': 'normal',
        'textStyle': 'normal',
        'textSize': 14,
        'textFont': null,
        'textFill': '#FFFFFF',
        'textOpacity': 1,
      }
    });
    text.addTo(boundaryVectorLayers);
  }

  // 初始化基础图层
  _initializeBaseLayers() {
    layerConfig.forEach(layerInfo => {
      const {id, urlTemplate, subdomains, cssFilter} = layerInfo;
      if (!id || !urlTemplate) {
        console.error(`Invalid layer configuration for layer ${id}. Skipping layer.`);
        return;
      }
      // eslint-disable-next-line no-undef
      const layer = new kcgis.TileLayer(id, {
        urlTemplate, subdomains: subdomains || [], cssFilter: cssFilter || ''
      });
      this._map.addLayer(layer);
    });
  }

  // 初始化矢量图层
  _initializeVectorLayers() {
    // eslint-disable-next-line no-undef
    this._vectorLayers = new kcgis.VectorLayer('vector-layers', {
      collision: true,
      collisionDelay: 300,
      forceRenderOnMoving: true,
      forceRenderOnZooming: true,
      forceRenderOnRotating: true,
    }).addTo(this._map);
  }

  // 添加原生多边形
  addNativePolygon(polygonData, htmlData) {
    if (!polygonData || !polygonData.length) return;
    const polyList = this._createPolygonList(polygonData);
    this._vectorLayers.addGeometry(polyList);
    this._vectorLayers.hide();
    this._moveToExtent(() => {
      this._vectorLayers.show();
      if (htmlData && htmlData.length) {
        this.addHtmlMarker(htmlData);
      }
    });
  }

  // 创建多边形列表
  _createPolygonList(polygonData) {
    return polygonData.map(item => {
      // 创建多边形
      const polygon = new kcgis.Polygon(item.polyArr[0] || [], {
        symbol: {
          lineColor: item.style.color || '#34495e',
          lineWidth: 0.4,
          polygonFill: item.style.color || '#ffffff',
          polygonOpacity: item.style.alpha || 0.6
        }
      });

      // 如果存在标签，则创建标签
      if (item.label) {
        const center = polygon.getCenter();
        const label = new kcgis.Label(item.label.text || '', [center.x, center.y], {
          collision: true, textSymbol: {
            textFaceName: 'YouSheBiaoTiHei sans-serif',
            textFill: item.label.textStyle.fillColor || '#ffffff',
            textHaloFill: item.label.textStyle.outlineColor || '#ffffff',
            textWeight: 'bold',
            textStyle: 'italic',
            textHaloRadius: 1,
            textSize: 12,
          }
        });
        return [polygon, label];
      }
      return [polygon];
    }).flat();
  }

  // 添加HTML标记
  addHtmlMarker(htmlData) {
    if (!htmlData || !htmlData.length) return;
    this._uiMarkers = htmlData.map(f => new kcgis.ui.UIMarker([f.x, f.y], {
      collision: true,
      collisionBufferSize: 2,
      collisionWeight: 1,
      collisionFadeIn: true,
      content: f.html,
      verticalAlignment: 'top',
      dy: -10
    }));

    this._uiMarkers.forEach(marker => marker.addTo(this._map));
  }

  // 添加自定义标记
  addCustomMarker(dataArray, callback) {
    if (!dataArray || !dataArray.length) return;

    const markers = this._createCustomMarkers(dataArray, callback);
    this._vectorLayers.hide();
    markers.forEach(marker => marker.addTo(this._vectorLayers));
    this._moveToExtent(() => {
      this._vectorLayers.show();
    });
  }

  // 创建自定义标记
  _createCustomMarkers(dataArray, callback) {
    return dataArray.map(f => {
      // 创建标记
      const marker = new kcgis.Marker([f.x, f.y], {
        symbol: {
          markerFile: './images/poi.png',
          markerWidth: 79 / 2,
          markerHeight: 263 / 2,
          markerDx: 0,
          markerDy: 0,
          markerOpacity: 1
        }
      });
      // 设置信息窗口
      marker.setInfoWindow({
        custom: true,
        autoOpenOn: 'click',
        autoCloseOn: 'click',
        dy: -255,
        collision: true,
        collisionBufferSize: 2,
        collisionWeight: 1,
        collisionFadeIn: true,
        content: this._buildInfoWindow(f, callback)
      });
      return marker;
    });
  }

  // 构建信息窗口
  _buildInfoWindow(item, callback) {
    const container = document.createElement('div');
    container.innerHTML = `
      <div class="blue-popup blue-popup-theme-06e34a">
        <div class="blue-popup-wrap">
          <div class="area">
            <div class="arrow-lt"></div>
            <div class="b-t"></div>
            <div class="b-r"></div>
            <div class="b-b"></div>
            <div class="b-l"></div>
            <div class="arrow-rb"></div>
            <div class="label-wrap">
              <div class="title">基地信息</div>
              <div class="label-content">
                <div class="data-li">
                  <div class="data-label">基地名称：</div>
                  <div class="data-value">${item.baseName}</div>
                </div>
                <div class="data-li">
                  <div class="data-label">基地地址：</div>
                  <div class="data-value">${item.address}</div>
                </div>
                <div class="data-li">
                  <div class="data-label">植物品种：</div>
                  <div class="data-value">${item.plantVariety}</div>
                </div>
                <div class="data-li">
                  <div class="data-label">负&nbsp;&nbsp;责&nbsp;&nbsp;人：</div>
                  <div class="data-value">${item.principal}</div>
                </div>
                <div class="data-li">
                  <div class="data-label">
                    <a id="twinLink" href="javascript:void(0)" style="color: red;">孪生展示</a>
                  </div>
                </div>
              </div>
            </div>
          </div>
          <div class="b-t-l"></div>
          <div class="b-b-r"></div>
        </div>
        <div class="arrow"></div>
      </div>
    `;
    container.querySelector('#twinLink').addEventListener('click', () => callback(item));
    return container;
  }

  // 清除所有矢量图层
  clearAllVectorLayer(isZoom = false) {
    if (this._vectorLayers && this._vectorLayers.getCount() > 0) {
      this._vectorLayers.clear();
    }
    this.clearAllUIMarkers();
    if (isZoom) {
      this._map.animateTo({
        zoom: mapConfig.zoom, center: mapConfig.center
      }, {
        duration: 500, easing: 'out'
      });
    }
  }

  // 清除所有UI标记
  clearAllUIMarkers() {
    if (this._uiMarkers && this._uiMarkers.length) {
      this._uiMarkers.forEach(marker => marker.remove());
      this._uiMarkers = [];
    }
  }

  // 移动到特定的Extent
  _moveToExtent(callback) {
    const extent = this._vectorLayers.getExtent();
    this._map.fitExtent(extent, 0, {animation: true, duration: 500}, (frame) => {
      if (frame.state.playState === "finished") {
        callback();
      }
    });
  }

  initKrigingLayer(data, legendInfo) {
    console.log(">>>>>>>>开始构建分析点");
    const dataset = this._createFeatureCollection(data);
    console.log(">>>>>>>>构建分析点完成,共计：" + dataset.features.length + "个分析点");
    const max = this._getMaxValue(data, 'value');
    console.log(">>>>>>>>分析点最大值为：" + max);
    this._worker.postMessage({
      taskType: 'kriging', data: {dataset, legendInfo, max, hnJson}
    });
  }


  _addKrigingContoursToMap(krigingContours, legendInfo) {
    const _this = this;
    console.log(">>>>>>>>裁剪完成,进行前端渲染", krigingContours);
    if (krigingContours?.features?.length > 0) {
      const polyList = [];
      krigingContours.features.forEach(feature => {
        const {coordinates} = feature.geometry;
        const polygonFill = _this._getColorForValue(legendInfo.label.legendInfo, feature.properties.level) || '#ffffff';
        coordinates.forEach(coordinate => {
          // eslint-disable-next-line no-undef
          const geometries = new kcgis.Polygon(coordinate, {
            symbol: {
              lineWidth: 0, polygonFill, polygonOpacity: 0.9
            }
          });
          polyList.push(geometries)
        });
      });
      _this._vectorLayers.addGeometry(polyList);
    }
    console.log(">>>>>>>>渲染完成");
  }

  _getColorForValue(data, value) {
    if (!data || data.length === 0) {
      return null; // 如果 data 不存在或为空数组，返回 null
    }
    for (const item of data) {
      const [min, max] = item.text.split('-').map(Number);
      if (value >= min && value <= max) {
        return item.color;
      }
    }
    return null; // 如果没有找到匹配的区间，则返回 null
  }

  _getMaxValue(data, property) {
    return Math.max(...data.map(d => d[property]));
  }

  _createFeatureCollection(data) {
    return {
      type: "FeatureCollection", features: data.map(d => ({
        type: "Feature", properties: {level: d.value}, geometry: {type: "Point", coordinates: [d.lon, d.lat]}
      }))
    };
  }

}

// 类代理，用于绑定方法到类实例
function classProxy(target) {
  const functionMap = new WeakMap();
  const handler = {
    get(target, key) {
      const value = Reflect.get(target, key);
      if (typeof value === 'function') {
        if (!functionMap.has(value)) {
          functionMap.set(value, value.bind(target));
        }
        return functionMap.get(value);
      }
      return value;
    }
  };
  return new Proxy(target, handler);
}

const mapApi = classProxy(new GisApi());
export default mapApi;
